﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Diagnostics;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Collections.ObjectModel;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.Collections.Specialized;
using BdcAdmin = Microsoft.SharePoint.BusinessData.Administration;
using Microsoft.Office.Server.Utilities;
using Microsoft.BusinessData;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.BusinessData.Administration;
using Microsoft.SharePoint.BusinessData.SharedService;
using Microsoft.SharePoint.BusinessData.MetadataModel;

namespace CenterSiteVSTemplateWizard
{
    public partial class EntityCenterInputForm : Form
    {

        public string entityNameproperty;
        public string entityNameSpaceproperty;
        public string lobSystempInstanceroperty;
        public string specificFinderproperty;
        public string Finderproperty;
        public NameValueCollection fields;
        public static string spportalName =Program.URL;

        public EntityCenterInputForm()
        {
            InitializeComponent();
        }

        
        private void nextButton_Click(object sender, EventArgs e)
        {
            entityNameproperty = comboBox1.SelectedItem.ToString();
            entityNameSpaceproperty = comboBox2.SelectedItem.ToString();
            lobSystempInstanceroperty = comboBox3.SelectedItem.ToString();
            specificFinderproperty = comboBox4.SelectedItem.ToString();
            Finderproperty = comboBox5.SelectedItem.ToString();             
            /* get the list fields in findermethod for the entity */
            fields = InitializeEntityFields(entityNameproperty, entityNameSpaceproperty, Finderproperty);

            this.Hide();
            Program.form2 = new EntityDetailsInputForm(fields);          
            Program.form2.Show();

        }

        /* ge the AdministrationMetadacatalog for Sharepoint */
        internal AdministrationMetadataCatalog GetAdministrationMetadataCatalog(SPServiceContext serviceContext)
        {
            
            AdministrationMetadataCatalog result = null;

            BdcService bdcService = SPFarm.Local.Services.GetValue<BdcService>(String.Empty);
            if (bdcService != null)
            {
                result = bdcService.GetAdministrationMetadataCatalog(serviceContext);
            }

            return result;

        }

        /* get the list of fields in finder method for given entity */
        internal NameValueCollection InitializeEntityFields(string en, string ens, string sf)
        {
            NameValueCollection result = new NameValueCollection();

            string entityName = en;
            string entityNamespace = ens;
            string finderName = sf;
            BdcAdmin.AdministrationMetadataCatalog catalog;

            SPSite spSite = new SPSite(spportalName);
            catalog = GetAdministrationMetadataCatalog(SPServiceContext.GetContext((spSite)));
            BdcAdmin.Entity entity = null;

            entity = catalog.GetEntity(entityNamespace, entityName);
         
            BdcAdmin.MethodInstanceCollection miCollection = entity.GetMethodInstances(Microsoft.BusinessData.MetadataModel.MethodInstanceType.Finder);
            BdcAdmin.MethodInstance Finder = null;
            foreach (BdcAdmin.MethodInstance mi in miCollection)
            {
                if (mi.Name == finderName)
                {
                    Finder = mi;
                    break;
                }
            }

            /* build the fields; fields can be complex types */
            foreach (Microsoft.SharePoint.BusinessData.Administration.TypeDescriptor td in Finder.ReturnTypeDescriptor.ChildTypeDescriptors)
            {
                BuildRecursive(td, td.Name, result);
            }

            return result;
        }

        /* this is recursion method, getting the fields in finder method. fields can be complex types*/
        private void BuildRecursive(BdcAdmin.TypeDescriptor td, string fieldPath, NameValueCollection result)
        {
            bool hasChild = false;
            foreach (BdcAdmin.TypeDescriptor tdChild in td.ChildTypeDescriptors)
            {
                hasChild = true;
                //BuildRecursive(tdChild, fieldPath + "." + tdChild.Name, result);
                BuildRecursive(tdChild, tdChild.Name, result);
            }

            if (!hasChild)
                result.Add(fieldPath, td.TypeName);

        }      
       
        /* ISV selected the entity name, we need to populate remainging combobox with appropriate values */
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            nextButton.Enabled = true;
            EntityCollection result;
            comboBox2.Items.Clear();
            comboBox3.Items.Clear();
            comboBox4.Items.Clear();
            comboBox5.Items.Clear();

            BdcAdmin.AdministrationMetadataCatalog catalog;

            SPSite spSite = new SPSite(spportalName);
            catalog = GetAdministrationMetadataCatalog(SPServiceContext.GetContext((spSite)));
            string entityname = comboBox1.SelectedItem.ToString();

            result = catalog.GetEntities("*", entityname, true);
            foreach (BdcAdmin.Entity ent in result)
            {
                comboBox2.Items.Add(ent.Namespace);
                BdcAdmin.LobSystem ls = ent.LobSystem;
                foreach (BdcAdmin.LobSystemInstance lsi in ls.LobSystemInstances)
                {
                    comboBox3.Items.Add(lsi.Name);
                }

                BdcAdmin.MethodInstanceCollection miCollection = ent.GetMethodInstances(Microsoft.BusinessData.MetadataModel.MethodInstanceType.SpecificFinder);
                foreach (BdcAdmin.MethodInstance mi in miCollection)
                {
                    comboBox4.Items.Add(mi.Name);
                }
                miCollection = ent.GetMethodInstances(Microsoft.BusinessData.MetadataModel.MethodInstanceType.Finder);
                foreach (BdcAdmin.MethodInstance mi in miCollection)
                {
                    comboBox5.Items.Add(mi.Name);

                }
            }
            if (comboBox2.Items.Count > 0)
                comboBox2.SelectedIndex = 0;
            else
                comboBox2.ResetText();

            if (comboBox3.Items.Count > 0)
                comboBox3.SelectedIndex = 0;
            else
                comboBox3.ResetText();

            if (comboBox4.Items.Count > 0)
                comboBox4.SelectedIndex = 0;
            else
                comboBox4.ResetText();

            if (comboBox5.Items.Count > 0)
                comboBox5.SelectedIndex = 0;
            else
                comboBox5.ResetText();
            
            
        }

        /* when form loads, we want to display list of entities which have finder method in first comboBox(entity name comboBox */

        private void EntityCenterInputForm_Load(object sender, EventArgs e)
        {
            try
            {

                EntityCollection result;

                BdcAdmin.AdministrationMetadataCatalog catalog;

                SPSite spSite = new SPSite(spportalName);
                catalog = GetAdministrationMetadataCatalog(SPServiceContext.GetContext((spSite)));

                result = catalog.GetEntities("*", "*", true);
                foreach (BdcAdmin.Entity ent in result)
                {
                    BdcAdmin.MethodInstanceCollection miCollection = ent.GetMethodInstances(Microsoft.BusinessData.MetadataModel.MethodInstanceType.Finder);
                    bool finderMethodExists = false;
                    foreach (BdcAdmin.MethodInstance mi in miCollection)
                    {
                        finderMethodExists = true;
                        break;
                       
                    }
                    if (finderMethodExists)
                        comboBox1.Items.Add(ent.Name);
                   
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }         

            
        }
  

 }
}
